Bevezets a Visual Basic-be (VB 3.0-ra alapozva)
================================================
tdik rsz


Els mondatknt elg lesz ennyi: a fjlkezelsrl lesz sz.

Szvegfjlok olvassa
-=-=-=-=-=-=-=-=-=-=-

Ha akarunk valamit kezdeni egy fjllal, akr olvasni belle, akr rni bele, elszr meg kell nyitnunk. Ezt az Open paranccsal rhetjk el. Ennek formtuma:

Open >Mit< for >Mire< As >#Csatorna<

(Remlem sikerlt megijeszteni tged.) Itt a >< jelek kztt a

Mit - a fjlnev. Lehetne pldul "c:\autoexec.bat", "c:\elso\masodik\harmadik.txt", vagy csak simn "abc.def". Ebbl azt lehet leszrni, hogy meg lehet adni a teljes elrsi tvonalat is, de ha nem adod meg, akkor az aktulis knyvtrrl lesz sz.
Mire - ez adja meg, hogy olvassra vagy rsra nyitod meg a fjlt. Szvegfjloknl a hrom legfontosabb: Input (olvassra), Output (rsra), Append (rsra, de mr meglev fjlhoz hozzfzi). Az Output-tal vatosan kell bnni, hogyha egy ltez fjlt nyitunk meg gy, akkor annak a tartalma elveszik, s semmi nem hozza vissza (hacsak nem egy biztonsgi msolat)
#Csatorna - hnyas csatornn nyitod meg. Logikus dolog az egyesen kezdeni. Ez arra j, hogy egyszerre tbb fjlt is meg tudj nyitni, mondjuk az egyest olvassra, a kettest rsra. Egy csatornt csak egyszer nyithatunk meg.

Akkor lerok egy pr pldt is, ahogy szoktam:

Open "c:\autoexec.bat" for input as #1 (olvassra az autoexec.bat-ot)
Open "adatok.dat" for append as #2 (rsra-hozzfzssel az adatok.dat-ot)
Open "uj.txt" for output as #3 (rsra az uj.txt-et)

Ha mr megtanultuk a fjlok megnyitst, tanuljuk meg a lezrst is! Ezt a Close utastssal lehet, paramterknt a csatornt kell megadnunk.

Close #1 (lezrja az egyest)
Close #2 (... a kettest)
Close #3 (... a hrmast)

Ez eddig nagyszer, most mr csak dolgozni kne a fjlokkal. Szvegfjlokrl van sz, ezrt mondjuk azt csinljuk, hogy beolvassuk az els sort az config.sys-ben, s azt egy message box-ban kiiratjuk.

Open "c:\config.sys" for input as #1
Line Input #1,Sor$
MsgBox Sor$
Close #1

Teht egy sort gy tudunk kiolvasni, hogy Line Input, utna a csatorna szma s a vltoz, amibe akarjuk rakni.

Hasznos lehet mg itt az EOF fggvny is. Paramterknt csatornaszmot kell megadnunk, s nullt ad vissza, ha a fjl mg nem rt vget, egyet ha mr igen. Hol lehet ez hasznos? Ha az sszes sort be akarjuk olvasni! Pldul ha egy ListBox-ba be akarjuk olvasni a config.sys tartalmt, akkor gy kell eljrnunk (felttelezve, hogy a ListBox neve List1):

Sub Command1_Click ()
  Open "c:\config.sys" for input as #4
  Do Until EOF(4)
    Line Input #4,Sor$
    List1.AddItem Sor$
  Loop
  Close #4
End Sub

Szvegfjloknl, olvassnl nem olyan nagy tragdia, ha nem zrod le a vgn a fjlt, de azrt szp dolog ezt megtenni. Ha nem tudod, hogy hnyas az els szabad csatorna (amit mg nem nyitottunk meg), akkor a megoldst a FreeFile fggvny jelenti. Paramternek nem kell semmi, a legels szabad csatornt adja vissza. Teht ha biztonsgosabban akarjuk megoldani az elz programot, akkor gy mdosul a kdunk:

Sub Command1_Click ()
  Csatorna = FreeFile
  Open "c:\config.sys" For Input As Csatorna
  Do Until EOF(Csatorna)
    Line Input #Csatorna, Sor$
    List1.AddItem Sor$
  Loop
  Close #Csatorna
End Sub

Figyeld meg, ha vltozt adsz meg csatornaszmknt, akkor az Open sornl nem kell # jelet alkalmazni. Mshol azonban kell. Hogy mirt van gy, azt nem tudom, de gy van.

rdemes azt is kiprblni, hogy mi trtnik, ha nem ltez fjlt nyitunk meg:

Open "c:\dsadasdfjklasfhewyr8i.sdkdak" for Input as #1

Ez run-time error-ral jr, s a program le fog llni. Ha ezt meg akarjuk elzni, neknk kell kzbe venni az irnytst.

On Error Resume Next
Mit$ = InputBox("Melyik fjlt nyissam meg?")
Open Mit$ for Input as #1
If Err <> 0 Then
  MsgBox "A fjl nem ltezik!"
  Close #1
  Exit Sub
End If
Do Until EOF(1)
  Line Input #1,Sor$
  List1.AddItem Sor$
Loop
Close #1

A fenti kis programrszlet az ltalunk megadott fjlt fogja megnyitni, de ha nem ltezik, akkor sem tr ki a balh.

Teht tvehetjk az I/O hibk kezelst a VB-tl, az On Error fggvnnyel. Ekkor a program nem ll le, hanem az Err nevezet vltozban eltroldik a hiba kdja, s ott is marad, amg le nem krdezzk. Az On Error kifejezs utn hasznlhatunk Resume Next-et (ekkor a program futsa folytatdik), vagy Goto XY-t is. Ekkor nem folytatdik a program, hanem elugrik a megadott cimkre. Teht a fenti programot gy is megvalsthatnnk:

Sub Command2_Click ()  
  On Error GoTo Hiba:
  Mit$ = InputBox("Melyik fjlt nyissam meg?")
  Open Mit$ For Input As #1
  Do Until False
    Line Input #1, Sor$
    List1.AddItem Sor$
  Loop


Hiba:
  If Err = 53 Then
    MsgBox "A fjl nem tallhat!"
    Close #1
    Exit Sub
  End If
  If Err = 62 Then
    Close #1
    Exit Sub
  End If
  Resume
End Sub 

Itt kell mg megemlteni a Resume-ot is, ez visszaugrik oda, ahol a hiba trtnt. A Resume nem hagyhat el, mindenkpp be kell tennnk a programba. Az nem szmt, ha esetleg soha nem fog lefutni, de ott kell lennie, klnben srni fog a fordt.

Most szpen levezetem, hogy hogyan fut le ez a programrszlet,

1. Ha rossz fjlnevet adtunk meg:

 - bekri a nevet
 - megnyitja a fjlt
 - a fjl nem ltezik, ezrt elugrik a Hiba: cimkre
 - "a fjl nem ltezik" hibakdja 53
 - kirja a hibazenetet
 - lezrja a fjlt
 - megszaktja az eljrs futtatst

2. Ha ltez fjlnevet adtunk meg:

 - bekri a nevet
 - megnyitja a fjlt
 - megvizsglja a feltlelt: False, ez soha nem teljesl
 - beolvas egy sort
 - beteszi a ListBox-ba
 - a fenti kt lpst addig ismtli, amg tl nem halad a fjl vgn
 - ekkor elugrik a Hiba: cimkre
 - a hibakd ebben az esetben 62.
 - lezrja a fjlt
 - megszaktja az eljrs futtatst 

Teht mkdik ez is, csak ht kevsb elegns... A hibakdok benne vannak a VB helpben, de a legfontosabbakat (amik a fjlkezelssel fggenek ssze) kigyjtm nektek:

53: A fjl nem ltezik
54: Fjl megnyitsi mdja hibs - ez akkor lp fel, ha mondjuk rsra nyitunk meg egy szvegfjlt, de olvasni akarunk belle.
55: A fjl mr meg van nyitva.
62: A fjlmutat elhagyta a fjl vgt
67: Tl sok fjl van nyitva
57 s 71: Nem tudja megnyitni a fjlt - pl. nincs bent a lemez, vagy az adathordoz megsrlt

Mg mindig nincs vge, lerok egy egyszer mdot arra, hogyan lehet egyszerre beolvasni az egsz fjlt, mondjuk egy TextBox-ba. Ekkor a TextBox MultiLine tulajdonsgt rdemes True-ra lltani, teht tbb sort is be lehessen vinni.

Open "c:\config.sys" for input as #1
Text1.Text = Input$(LOF(1), 1)
Close #1

Ennek a mdszernek a legnagyobb htrnya az, hogy max. 65536 bjt hossz szvegfjlokat tudunk vele beolvasni - legalbbis TextBox-ba.

Szvegfjlok rsa
-=-=-=-=-=-=-=-=-=

Elrkezett az id, hogy adatokat rjunk a programunkkal! 

Open "adatok.txt" for output as #1
Print #1,"Hehehehehehehehehe! Hahahahahaha! Hihihihi!"
Close #1

Ez itt ugye a legegyszerbb eset. Az adatok.txt-be a " jelek kztt lv karakterlncot fogja berni. Termszetesen megadhatunk vltozt is karakterlncknt. Ha szmokat akarunk fjlba rni, akkor rdemes ket eltte a CStr fggvnnyel karakterlncc konvertlni. Plda egy eljrsra, ami elszmol egytl szzig (a szamok.txt-ben teszi ezt):

Open "szamok.txt" For Output As #1
For X = 1 To 100
  Print #1, CStr(X)
Next X
Close #1

Nzd meg a klnbsget, ha csak simn, konvertls nlkl rod be a szmokat! (Teht Print #1,X) Undort, nem? Mert szerintem az. s hogy mirt van, arra megint nem tudok magyarzatot adni.

Akkor rdemes most egy kicsit a Close szereprl dumlni. Itt sokkal fontosabb, mint az olvassnl, mert ha nem zrod le a fjlt, akkor a "vltozatsok" nem rvnyeslnek. Teht megnyitsz egy j fjlt rsra, belersz hatszzezer bjt adatot, de nem zrod le, akkor egy nulla bjtos fjl fog szernykedni a gpeden. s ha Append-del nyitod meg a fjlt, hozzrsz valamit, de nem zrod le, akkor a hozzfztt adatok nem fognak hozzrdni a programhoz. Persze azrt nem olyan tragikus a helyzet, ha bezrsz egy programot (szablyosan, nem run-time error hatsra), akkor le fog zrdni minden megnyitott fjl. De azrt jobb, ha te vgzed el a lezrsokat, biztos ami biztos.

Vgezetl egy kis trkk, szintn a TextBox-okkal sszefggsben: nagyon egyszeren az egsz TextBox tartalmt a fjlba mentheted, mghozz gy:

Open "eztazt.txt" for output as #1
Print #1,Text1.Text
Close #1

Ezekkel az ismeretekkel neki lehet llni egy kis szvegszerkesztcske megrshoz :-) Ha pedig nem akarsz rni, nzd meg a MiniPad nev programot, ami itt van, ebben a ZIP fjlban. Teljesen alapszint, neki lehet llni kibvteni. Ezt most vletlenl 5.0-ban rtam, elnzst mindenkitl, akinek rgebbi van...

Ltezik-e a fjl?
-=-=-=-=-=-=-=-=-

Mieltt ttrnnk a binris fjlokra, mutatok egy apr trkkt. Ez egy fggvny, ami megnzi hogy ltezik-e mr a megadott fjl:

Function Letezik (Mi As String)
  On Error Resume Next
  M = FreeFile
  Open Mi For Input As M
  Close #M
  If Err = 0 Then
    Letezik = 1
  Else
    Letezik = 0
  End If
End Function

Eggyel tr vissza ha igen, nullval ha nem. Ezt mr tbben krdeztk tlem, a Visual Basic zna eddigi, csaknem msfl ves trtnete sorn.

A binris megnyitsi md
-=-=-=-=-=-=-=-=-=-=-=-=

Direkt nem rtam binris fjlok megnyitst, mert vglis binris fjlokat is meg lehet nyitni szvegknt, meg szvegfjokat is meg lehet nyitni binrisknt. (Szeretem megkavarni a dolgokat :-) )

Ebbe a tmba nem fogok kell rszletessggel belemenni, mert szerintem ezt a tmt nem az alapoknl kne trgyalni. Ennek megfelelen a magyarzat itt-ott kicsit furcsa, itt-ott kicsit rthetetlen... Na j, azrt remlem hogy nem annyira rthetlen.

A binris md fleg rekordok rgztsnl s beolvassnl hasznos. A rekordokrl eddig mg nem volt sz, nem emltettem mg a nulladik rszben sem.

Tegyk fel, hogy egy olyan programot kell rnunk, amelyben rgztjk egy cg alkalmazottainak nevt, szletsi vt s fizetst. A cgnek van mondjuk 100 alkalmazottja. Ezt megtehetnnk gy, hogy hrom tmbt alkalmazunk:

Dim Nev(100) As String * 20
Dim SzuletesiEv(100) As Integer
Dim Fizetes(100) As Long

Ennl azonban sokkal elegnsabb megolds, ha egy rekordot hozunk ltre, ami lnyegben egy jfajta vltoztpus deklarlsa. A fenti pldnl maradva:

Type TDolgozok
  Nev As String * 20
  SzuletesiEv As Integer
  Fizetes As Long
End Type

(A fenti nhny sort egy kln BAS fjlban, azaz modulban kell rgztennk, a lejjebb tallhatt pr sort pedig a (General) rsznl)

Dim Dolgozok(100) As TDolgozok

Ezek utn gy tudunk hivatkozni a rekordra:

Dolgozok(0).Nev = "Sndor Gbor"
Dolgozok(0).SzuletesiEv = 1965
Dolgozok(0).Fizetes = 75000
Dolgozok(1).Nev = "Vitrovszky Tams"
Dolgozok(1).SzuletesiEv = 1974
Dolgozok(1).Fizetes = 100000
...
Dolgozok(100).Nev = "Gipsz Jakab"
Dolgozok(100).SzuletesiEv = 1999
Dolgozok(100).Fizetes = 25000

Aki figyelt, az rjtt hogy ez nem szz, hanem szzegy elem :-)

Ez a megolds azrt jobb, mert egyrszt elegnsabb, msrszt a rekord a memriban egy helyen helyezkedik el, harmadrszt mert gy VB-ben knnyebben tudjuk rgzteni s visszaolvasni.

Ezek utn, ha rgzteni akarjuk, akkor azt gy rdemes:

Open "dolgozok" For Binary As #1
For X = 0 To 100
  Put #1, , Dolgozok(X)
Next X
Close #1

Mg ha hrom klnbz tmbt hasznltunk volna, akkor gy nzne ki:

Open "dolgozok" For Output as #1
For X = 0 To 100
  Print #1,Nev(X)
  Print #1,SzuletesiEv(X)
  Print #1,Fiztes(X)
Next X
Close #1

Teht binris mdban a Put utastssal tudunk adatok rgzteni. Az els paramter a megszokott mdon a csatorna, a msodikkal ksbb foglalkozunk, de elhagyhat, a harmadik pedig a rgztend adat (ami lehet rekord is).

Ugyanilyen knnyen vissza is tudjuk olvasni az adatainkat:

Open "dolgozok" for Binary as #1
For X = 0 to 100
  Get #1, , Dolgozok(X)
Next X
Close #1

Lthatjuk, hogy ugyanilyen elven mkdik a Get utasts is.

Valamirl mg nem volt sz, mghozz arrl, hogy hogyan dnti el a VB (binris megnyitsi md esetn), hogy ezt a fjlt most rni vagy olvasni akarjuk. Nos, megnyits esetn, ha a fjl nem ltezik, akkor ltrehozza, ha mr ltezik, akkor nem bntja (maximum mi bntjuk, ha belerunk valamit). Ha mi akarjuk megadni, hogy ezt a fjlt csak olvasni akarjuk, vagy csak rni akarjuk, akkor az Open sorunkba bele kell csempsznnk egy Access kulcsszt is, aminek rtke lehet "Read", "Write", s "Read Write".

Open "dolgozok" For Binary Access Read As #1
...
Close #1

Mi is az a msodik paramter? Ezzel azt adhatjuk meg, hogy hnyadik bjttl kezdjk meg a Put esetn az rst, Get esetn az olvasst. Nem foglalkozunk vele bvebben.


A msik helyzet, amikor a binris md hasznos lehet az, amikor egy fjlt bjtonknt kell feldolgozni. Tegyk fel, hogy egy titkostprogramot runk, aminek az elve nagyon egyszer: minden bjthoz hozzad mg 15-t. (Ami nem szmt komoly titkostsnak.)

gy valsthatjuk meg:

Dim Bajt As String * 1
Open "forras" for Binary as #1
Open "cel" for Binary As #2
Do Until Eof(1)
  Get #1,,Bajt
  Bajt = Chr(Asc(Bajt)+15)
  Put #1,,Bajt
Loop
Close #1
Close #2

Elrkeztnk az tdik rsz vghez. Mr ltom, ahogy elkezded ismt olvasni ezt az utols rszt, de ne tedd :-) Tudom, nagyon rosszul sikerlt, majd valamikor trom... De ha tnyleg csak most kezded a VB tanulst, szerintem nem olyan nagy tragdia, ha ez a rsz ideiglenesen kimarad az letedbl. 



Ezt azt iromnyt Kvi Blint ksztette. Fellem azt csinlsz vele, amit akarsz, trhatod, de azrt emlts meg engem is, j? Frisstseket, folytatsokat mindig tallhatsz a Visual Basic znban: http://vbzona.fw.hu/